package com.shallowUniverse.process.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.shallowUniverse.process.entity.ProcessNodeDefinition;
import com.shallowUniverse.process.exception.ProcessNotCompletedException;
import com.shallowUniverse.process.mapper.ApprovalMapper;
import com.shallowUniverse.process.mapper.ProcessNodeDefinitionMapper;
import com.shallowUniverse.process.service.ProcessNodeDefinitionService;
import com.shallowUniverse.process.utils.AssertUtil;
import com.shallowUniverse.process.utils.ProcessUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.Map;

/**
 * @author gs
 * @date create in 2020/12/11 16:07
 */
@AllArgsConstructor
public class ProcessNodeDefinitionServiceImpl implements ProcessNodeDefinitionService {

    private final ProcessNodeDefinitionMapper processNodeDefinitionMapper;
    private final ApprovalMapper approvalMapper;

    @Override
    public List<ProcessNodeDefinition> findFirstNode(Long processId) {
        return processNodeDefinitionMapper.selectFirtstNode(processId);
    }

    @Override
    public List<ProcessNodeDefinition> renderNextNode(ProcessNodeDefinition processNodeDefinition) {
        return processNodeDefinitionMapper.selectNextNode(processNodeDefinition);
    }

    @Override
    public List<ProcessNodeDefinition> findByIds(List<Long> ids) {
        return processNodeDefinitionMapper.selectById(ProcessUtil.parseCollectionToString(ids));
    }

    @Override
    public String findFieldValue(Map<String, String> params) {
        return processNodeDefinitionMapper.selectFieldValue(params);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int save(ProcessNodeDefinition processNodeDefinition) {
        if (ObjectUtils.isEmpty(processNodeDefinition)) {
            return 0;
        }
        if (ObjectUtils.isEmpty(processNodeDefinition.getCreateDate())) {
            processNodeDefinition.setCreateDate(DateUtil.now());
        }
        return processNodeDefinitionMapper.insert(processNodeDefinition);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int saveBatch(List<ProcessNodeDefinition> processNodeDefinitions) {
        if (CollectionUtils.isEmpty(processNodeDefinitions)) {
            return 0;
        }
        processNodeDefinitions.iterator().forEachRemaining(processNodeDefinition -> {
            if (ObjectUtils.isEmpty(processNodeDefinition.getCreateDate())) {
                processNodeDefinition.setCreateDate(DateUtil.now());
            }
        });
        return processNodeDefinitionMapper.insertBatch(processNodeDefinitions);
    }

    @Override
    public int update(ProcessNodeDefinition processNodeDefinition) {
        if (ObjectUtils.isEmpty(processNodeDefinition)) {
            return 0;
        }
        return processNodeDefinitionMapper.update(processNodeDefinition);
    }

    @Override
    public int updateBatch(List<ProcessNodeDefinition> processNodeDefinitions) {
        if (CollectionUtils.isEmpty(processNodeDefinitions)) {
            return 0;
        }
        return processNodeDefinitions.stream().mapToInt(processNodeDefinitionMapper::update).sum();
    }

    @Override
    public List<ProcessNodeDefinition> find(ProcessNodeDefinition processNodeDefinition) {
        return processNodeDefinitionMapper.selectList(processNodeDefinition);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int remove(List<Long> ids, boolean isLogic) throws ProcessNotCompletedException {
        //判断是否传了id
        if (CollectionUtils.isEmpty(ids)) {
            return 0;
        }
        //判断是否存在未完成的流程
        AssertUtil.processNotCompleted(approvalMapper.selectNotCompletedByProcessNode(ProcessUtil.parseCollectionToString(ids)));
        //判断是逻辑删除还是直接删除
        if (isLogic) {
            return processNodeDefinitionMapper.deleteLogic(ProcessUtil.parseCollectionToString(ids));
        } else {
            return processNodeDefinitionMapper.delete(ProcessUtil.parseCollectionToString(ids));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int removeByProcess(List<Long> processIds, boolean isLogic) throws ProcessNotCompletedException {
        //判断是否传了id
        if (CollectionUtils.isEmpty(processIds)) {
            return 0;
        }
        //判断是否存在未完成的流程
        AssertUtil.processNotCompleted(approvalMapper.selectNotCompletedByProcess(ProcessUtil.parseCollectionToString(processIds)));
        //判断是逻辑删除还是直接删除
        if (isLogic) {
            return processNodeDefinitionMapper.deleteByProcessLogic(ProcessUtil.parseCollectionToString(processIds));
        } else {
            return processNodeDefinitionMapper.deleteByProcess(ProcessUtil.parseCollectionToString(processIds));
        }
    }

    @Override
    public IPage<ProcessNodeDefinition> findPage(IPage<ProcessNodeDefinition> page, ProcessNodeDefinition processNodeDefinition) {
        //返回
        return processNodeDefinitionMapper.selectPageList(page, processNodeDefinition);
    }

    @Override
    public List<ProcessNodeDefinition> findMaxNodeByRole(Map<String, String> params) {
        return processNodeDefinitionMapper.selectMaxNodeByRole(params);
    }
}
